﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using NCLCustomerManagement.BusinessLogic.Category;
using NCLCustomerManagement.BusinessLogic.Products;
using NCLCustomerManagement.DataTransferObjects.Product;
using NCLCustomerManagement.UI.Helper;
using NCLCustomerManagement.UI.Models.ProductCategory;

namespace NCLCustomerManagement.UI.Controllers
{
    public class ProductController : BaseController
    {
        private IProductBC _productBC;
        private ICustomerBC _customerBC;

        public ProductController(IBCFactory bcFactory)
        {
            _productBC = bcFactory.GetBC<IProductBC>();
            _customerBC = bcFactory.GetBC<ICustomerBC>();
        }

        [AuthenticationRequired]
        public ActionResult Index(int Category = -1, string ProductName = "")
        {
            var products = _productBC.GetAllProducts();
            if (Category != -1)
            {
                products = products.Where(e => e.ProductCategoryId == Category);
            }

            var productModels = products.Where(e => e.ProductName.ToLower().Contains(ProductName.ToLower()))
             .Select(e => AutoMapperBuilder.MapSourceToDestination<ProductDTO, ProductModel>(e))
             .ToList();
            foreach (var item in productModels)
            {
                item.TotalUseTimeString = this.RepresentTime(item.QuantityPerUnit / item.UsedPerDay);
            }
            PrepareCategorySelectListWithProductCount();
            ViewBag.SearchProductName = ProductName;
            return View(productModels);
        }

        [AuthenticationRequired]
        [HttpGet]
        public ActionResult GetProductListPartial(int Category = -1, string ProductName = "")
        {
            var products = _productBC.GetAllProducts();
            if (Category != -1)
            {
                products = products.Where(e => e.ProductCategoryId == Category);
            }

            var productModels = products.Where(e => e.ProductName.ToLower().Contains(ProductName.ToLower()))
             .Select(e => AutoMapperBuilder.MapSourceToDestination<ProductDTO, ProductModel>(e))
             .ToList();
            foreach (var item in productModels)
            {
                item.TotalUseTimeString = this.RepresentTime(item.QuantityPerUnit / item.UsedPerDay);
            }
            PrepareCategorySelectListWithProductCount();
            ViewBag.SearchProductName = ProductName;
            return PartialView("_ProductListPartial", productModels);
        }

        [AuthenticationRequired]
        [HttpPost]
        public ActionResult GetProductListPartial(string Category, string ProductName)
        {
            return RedirectToAction("GetProductListPartial", new
            {
                Category = string.IsNullOrEmpty(Category)
                ? -1 : Convert.ToInt32(Category),
                ProductName = ProductName
            });
        }

        [HttpPost]
        [AuthenticationRequired]
        public ActionResult Index(string Category, string ProductName)
        {

            return RedirectToAction("Index", new
            {
                Category = string.IsNullOrEmpty(Category)
                ? -1 : Convert.ToInt32(Category),
                ProductName = ProductName
            });
        }

        [AuthenticationRequired]
        public ActionResult New()
        {
            PrepareCategorySelectList();
            return View(new ProductModel());
        }

        private void PrepareCategorySelectList(int? selectedValue = null)
        {
            var cates = this.GetAllCategories(_customerBC).ToList();
            var cateSelectList = new SelectList(cates, "Id", "ProductCategoryName", selectedValue);
            ViewBag.CategorySelectList = cateSelectList;
        }

        private void PrepareCategorySelectListWithProductCount()
        {
            var cates = this.GetAllCategories(_customerBC)
                .Select(e => new ProductCategoryModel()
                {
                    Id = e.Id,
                    ProductCategoryName = string.Format("{0} ({1})", e.ProductCategoryName, _productBC.GetProductCountOf(e.Id))
                }).ToList();
            var cateSelectList = new SelectList(cates, "Id", "ProductCategoryName");
            ViewBag.Category = cateSelectList;
        }

        [HttpPost]
        [AuthenticationRequired]
        public ActionResult New(ProductModel product, int CategorySelectList, HttpPostedFileBase UploadImage)
        {
            if (UploadImage == null)
            {
                ModelState.AddModelError("", "Bạn hãy chọn file hình ảnh");
                PrepareCategorySelectList();
                return View(product);
            }
            var fileName = Path.GetFileName(UploadImage.FileName);
            var ext = Path.GetExtension(fileName);
            var filePath = Path.Combine(HttpContext.Server.MapPath("~/Upload/ProductImages"),
                                                   fileName);
            string newFilePath = "";
            try
            {
                if (UploadImage.ContentLength > 0)
                {

                    if (!ValidateUploadedImage(ext))
                    {
                        ModelState.AddModelError("", "Chỉ chấp nhận những file hình .jpg, .gif, .png");
                        PrepareCategorySelectList();
                        return View(product);
                    }
                    UploadImage.SaveAs(filePath);
                }

                string newFileName = string.Format("{0}{1}", Guid.NewGuid(), ext);
                newFilePath = Path.Combine(HttpContext.Server.MapPath("~/Upload/ProductImages"),
                                                  newFileName);
                System.IO.File.Move(filePath, newFilePath);
                product.ProductCategoryId = CategorySelectList;
                product.ImageUrl = newFileName;

                var dto = ConvertModelToDTO<ProductModel, ProductDTO>(product);

                _productBC.AddProduct(dto);
                return RedirectToAction("Index");
            }
            catch (Exception)
            {
                if (System.IO.File.Exists(newFilePath))
                {
                    System.IO.File.Delete(newFilePath);
                }
                ModelState.AddModelError("", "Đã xảy ra lỗi khi thêm");
                PrepareCategorySelectList();
                return View(product);
            }


        }

        [AuthenticationRequired]
        public ActionResult Edit(int id)
        {
            var dto = _productBC.GetProduct(id);
            if (dto == null)
                return new HttpNotFoundResult("Sản phẩm không tồn tại");
            var model = ConvertDTOToModel<ProductDTO, ProductModel>(dto);
            PrepareCategorySelectList(dto.ProductCategoryId);
            return View(model);
        }

        [AuthenticationRequired]
        [HttpPost]
        public ActionResult Edit(ProductModel product, int CategorySelectList, HttpPostedFileBase UploadImage)
        {


            try
            {
                if (UploadImage != null && UploadImage.ContentLength > 0)
                {
                    var fileName = Path.GetFileName(UploadImage.FileName);
                    var ext = Path.GetExtension(fileName);
                    var filePath = Path.Combine(HttpContext.Server.MapPath("~/Upload/ProductImages"),
                                                           fileName);
                    if (!ValidateUploadedImage(ext))
                    {
                        ModelState.AddModelError("", "Chỉ chấp nhận những file hình .jpg, .gif, .png");
                        PrepareCategorySelectList();
                        return View(product);
                    }
                    UploadImage.SaveAs(filePath);


                    string newFileName = string.Format("{0}{1}", Guid.NewGuid(), ext);
                    var newFilePath = Path.Combine(HttpContext.Server.MapPath("~/Upload/ProductImages"),
                                                       newFileName);
                    try
                    {
                        System.IO.File.Move(filePath, newFilePath);
                    }
                    catch
                    {
                        newFileName = fileName;
                    }

                    if (product.ImageUrl != null)
                    {
                        var existingFilePath = Path.Combine(HttpContext.Server.MapPath("~/Upload/ProductImages"),
                                                           product.ImageUrl);
                        System.IO.File.Delete(existingFilePath);
                    }
                    if (UploadImage != null)
                        product.ImageUrl = newFileName;
                }

                product.ProductCategoryId = CategorySelectList;
                var dto = ConvertModelToDTO<ProductModel, ProductDTO>(product);
                _productBC.UpdateProduct(dto);
                return RedirectToAction("Index");
            }
            catch (Exception)
            {
                PrepareCategorySelectList();
                ModelState.AddModelError("", "Đã xảy ra lỗi khi sửa");
                return View(product);
            }

        }

        [AuthenticationRequired]
        public ActionResult Delete(int id)
        {
            _productBC.DeleteProduct(id);
            return RedirectToAction("Index");
        }
        private bool ValidateUploadedImage(string fileExt)
        {
            var fe = fileExt.ToLower();
            if (fe.Contains("jpg")
                || fe.Contains("png")
                || fe.Contains("gif")
                || fe.Contains("tiff"))
            {
                return true;
            }
            return false;
        }       
    }
}
